# coding: utf-8

# -------------------------------------------------------------------------------
# Name:         sql_runner.py
# Description:
# Author:       XiangjunZhao
# EMAIL:        2419352654@qq.com
# Date:         2022/8/14 21:22
# -------------------------------------------------------------------------------
import json
import logging
import time

from django.utils import timezone

from apps.HttpAutoTestService.core.ext_methods import MysqlDB
from apps.HttpAutoTestService.core.http_session_context import HttpSessionContext
from apps.HttpAutoTestService.core.utils import regex_parse_args, parse_output_result, parse_sql_validate_result
from apps.HttpAutoTestService.models import SQLResult
from utils.common import CJsonEncoder

logger = logging.getLogger(__name__)


class SQLRunner(object):

    @classmethod
    def run(cls, http_session_context: HttpSessionContext = None, sql_desc=None, db_type=None, db_tag=None,
            db_name=None, operation_type=None, sql=None, expect_result=None, executor=None,
            is_periodictask=None) -> SQLResult:
        # 执行时间
        execute_time = timezone.now()
        # 开始时间，毫秒
        start_ms = time.time() * 1000
        expect_result = regex_parse_args(content=expect_result, http_session_context=http_session_context)
        expect_result = json.loads(expect_result) if expect_result else {}
        sql = sql.strip()
        if sql:
            sql = regex_parse_args(content=sql, http_session_context=http_session_context)
        else:
            raise Exception
        results = None
        if db_type.upper() == 'MYSQL':
            if operation_type == 'SELECT_ONE' and sql.upper().startswith('SELECT'):
                results = MysqlDB(mysql_tag=db_tag, db=db_name).query_one(sql=sql)
            elif operation_type == 'SELECT_MANY' and sql.upper().startswith('SELECT'):
                results = MysqlDB(mysql_tag=db_tag, db=db_name).query_many(sql=sql)

            if operation_type == 'EXECUTE' and (sql.upper().startswith('INSERT') or sql.upper().startswith('UPDATE')
                                                or sql.upper().startswith('DELETE')):
                MysqlDB(mysql_tag=db_tag).exec_one(sql=sql)
        else:
            # TODO
            pass

        # 存储提取输出的变量值
        output_result = parse_output_result(name=sql_desc, result={'results': results},
                                            expect_result=expect_result,
                                            http_session_context=http_session_context)
        output_result = output_result if output_result else ""
        variables_mapping = {**http_session_context.session_variables_mapping,
                             **http_session_context.output_variables_mapping}
        validate_pass, failure_reason = parse_sql_validate_result(result={'results': results},
                                                                  expect_result=expect_result,
                                                                  http_session_context=http_session_context)
        failure_reason = failure_reason if validate_pass == "FAIL" else ""
        # 结束时间，毫秒
        end_ms = time.time() * 1000
        elapsed_ms = round(end_ms - start_ms, 3)
        sql_ext = {'db_tag': db_tag, 'db_type': db_type, 'db_name': db_name, 'operation_type': operation_type}
        results = json.dumps(results, ensure_ascii=False, cls=CJsonEncoder)  # 为了将reults中的date、datetime、Decimal进行转化
        results = json.loads(results)
        sql_result = SQLResult(sql=sql, sql_desc=sql_desc, sql_ext=sql_ext, sql_run_result=results,
                               execute_time=execute_time, elapsed_ms=elapsed_ms, status=validate_pass,
                               failure_reason=failure_reason, executor_id=executor,
                               executor_real_name=executor.real_name, is_periodictask=is_periodictask,
                               output_result=output_result, context_global_variable=variables_mapping)
        return sql_result
